/////////////////////////////////////////////////////////////////////////////
// Name:        variantobjectset.h
// Purpose:     A variant type supporting a set of objects each with properties
// Author:      Julian Smart
// Modified by:
// Created:     2006-05-11
// RCS-ID:      $$
// Copyright:   (c) Julian Smart
// Licence:     wxWindows Licence
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_VARIANTPROPERTYOBJ_H_
#define _WX_VARIANTPROPERTYOBJ_H_

#include "wx/defs.h"
#include "wx/variant.h"

#include "variantref.h"

class wxImageBlock;

/*
 * A single object
 */

/*!
 * wxVariantObjectSetData stores the actual data and is ref-counted;
 */

class wxVariantObjectSetData: public wxClonableVariantData
{
DECLARE_DYNAMIC_CLASS(wxVariantObjectSetData)
public:

// Construction & destruction

    wxVariantObjectSetData();
    wxVariantObjectSetData(const wxVariantObjectSetData& data);
    ~wxVariantObjectSetData();

// OVERRIDEABLES

    /// Copy to data
    // virtual void Copy(wxVariantData& data);
    /// Clone
    virtual wxVariantData* Clone() { return new wxVariantObjectSetData(*this); }
    virtual bool Eq(wxVariantData& data) const;
    virtual bool Write(wxString& str) const;
    virtual bool Read(wxString& str);

    // What type is it? Return a string name.
    virtual wxString GetType() const { return wxT("objectset"); }

// NEW OPERATIONS

    /// Clear data
    void Clear();

    /// Delete image
    bool DeleteObject(size_t i);

    /// Get object
    wxVariant* GetObject(size_t i) const;

    /// Find object by name
    wxVariant* FindObject(const wxString& field, const wxString& name) const;

    /// Add data
    void AddObject(wxVariant* data);

    /// Get number of media objects
    size_t GetCount() const { return m_objects.GetCount(); }

private:

    /// List of variants
    wxList  m_objects;
};

// Useful functions

// Is this variant an object set?
bool wxIsVariantObjectSetData(const wxVariant& variant);

// Get the property object set data
wxVariantObjectSetData* wxGetVariantObjectSetData(const wxVariant& variant);

// Create property object set
wxVariant wxCreateVariantObjectSetVariant();

/// Set property
void wxVariantSetProperty(wxVariant& var, const wxString& name, const wxVariant& value);

/// Add property as string
void wxVariantSetProperty(wxVariant& var, const wxString& name, const wxString& value);

/// Set property
void wxVariantSetProperty(wxVariant& var, int i, const wxVariant& value);

/// Set property as string
void wxVariantSetProperty(wxVariant& var, int i, const wxString& value);

/// Find property as variant
wxVariant* wxVariantFindPropertyPtr(const wxVariant& var, const wxString& name);

/// Find property as variant
wxVariant wxVariantFindProperty(const wxVariant& var, const wxString& name);

/// Find property as string
wxString wxVariantFindPropertyString(const wxVariant& var, const wxString& name);

/// Get property as variant
wxVariant* wxVariantGetPropertyPtr(const wxVariant& var, int i);

/// Get property as variant
wxVariant wxVariantGetProperty(const wxVariant& var, int i);

/*!
 * wxVariantObjectSetAccessor: a class to make it easy to
 * manipulate an "objectset" wxVariant
 */

class wxVariantObjectSetAccessor
{
public:

// Construction

    wxVariantObjectSetAccessor(wxVariant& objectSet) { m_objectSet = & objectSet; }
    wxVariantObjectSetAccessor(wxVariant* objectSet) { m_objectSet = objectSet; }
    wxVariantObjectSetAccessor(const wxVariant* objectSet) { m_objectSet = (wxVariant*) objectSet; }

// Operations

    /// Is this an object set?
    bool IsValid() const;

    /// If not already an object set (could be null), make sure it is.
    bool MakeObjectSet();

    /// Clear the set
    bool Clear();

    /// Access the nth variant object in the set
    wxVariant* GetVariant(int n);
    wxVariant GetVariant(int n) const;

    /// Set the nth variant object
    void SetVariant(int n, const wxVariant& variant);

    /// Find the variant object by property name/value pair (e.g. Name, Julian)
    wxVariant* FindVariant(const wxString& property, const wxVariant& value);
    wxVariant* FindVariant(const wxString& property, const wxString& value);

    /// Find the variant index by pointer
    int FindVariantIndex(wxVariant* var);

    /// Add a variant
    void AddVariant(wxVariant* variant);

    /// Insert a variant at the given position
    void InsertVariant(wxVariant* variant, int pos);

    /// Delete a variant at the given position
    bool DeleteVariant(int pos);

    /// Delete a variant by name/value
//    bool DeleteVariant(const wxString& property, const wxVariant& value);
//    bool DeleteVariant(const wxString& property, const wxString& value);

    /// Get the property for the given variant object
    wxVariant* GetProperty(int var, int property);

    /// Find the named property in the given variant object
    wxVariant* FindProperty(int var, const wxString& propertyName);

    /// Find the index of the property in the given variant object
    int GetPropertyIndex(int var, const wxString& propertyName);

    /// Set the named property in the given variant object
    bool SetProperty(int var, const wxString& propertyName, const wxVariant& value);
    bool SetProperty(int var, const wxString& propertyName, const wxString& value);
    bool SetProperty(int var, int property, const wxVariant& value);
    bool SetProperty(int var, int property, const wxString& value);

    /// Set the property image
    bool SetPropertyImage(int var, int property, const wxImage& image, int type = wxBITMAP_TYPE_JPEG);
    bool SetPropertyImage(int var, int property, const wxString& filename, int type = wxBITMAP_TYPE_JPEG);
    bool SetPropertyImage(int var, const wxString& propertyName, const wxImage& image, int type = wxBITMAP_TYPE_JPEG);
    bool SetPropertyImage(int var, const wxString& propertyName, const wxString& filename, int type = wxBITMAP_TYPE_JPEG);

    /// Get the image, if any
    wxImage* GetPropertyImage(int var, int property);
    wxImage* FindPropertyImage(int var, const wxString& propertyName);

    /// Get the image block
    wxImageBlock* GetPropertyImageBlock(int var, int property);
    wxImageBlock* FindPropertyImageBlock(int var, const wxString& propertyName);

    /// Ensure image has been created from the data
    bool MakePropertyImage(int var, int property, bool force = false);
    bool MakePropertyImage(int var, const wxString& propertyName, bool force = false);

    /// Make a copy of the object set
    wxVariant Copy() const;

    /// Get the object set count
    int GetCount() const;

    /// Make sure we're the exclusive owner of the data
    void AllocExclusive() const;

// Accessors

    wxVariant* GetObjectSet() { return m_objectSet; }
    void SetObjectSet(wxVariant* objectSet) { m_objectSet = objectSet; }

    /// Get the data
    wxVariantObjectSetData* GetData() const;

private:
    wxVariant*      m_objectSet;
};




#endif
    // _WX_VARIANTPROPERTYOBJ_H_
